Katanemhmèna Sust mata II Mˆjhma EleÔjerhc Epilog c, EarinoÔ Exam nou Tomèac Efarmog n kai Jemeli sewn Ajanˆsioc KÐnalhc Meletˆme èna katanemhmèno sôsthma gia thn krˆthsh aeroporik n jèsewn Θέματα σχεδιασμού Διαφορετικές τεχνολογίες υλοποίησης Sqediˆsame to sôsthma wc proc thn Αποτύπωση Απαιτήσεων Συστήματος Αποτύπωση Λειτουργιών Συστήματος Use Cases Καταγραφή Προδιαγραφών Συστήματος Pèmpth, 10 Maòou, 2007 AÐjousa AP7 Katagrˆyame tic apait seic tou sust matoc Αναζήτηση πτήσεων Εμφάνιση ανοικτών θέσεων ανά πτήση Κράτηση θέσης Αναζήτηση κρατήσεων Apotup same tic leitourgðec tou sust matoc me thn qr sh Use Cases Αναζήτηση Πτήσης Επιλογή Πτήσης Ελεγχος Ελεύθερων Θέσεων Δέσμευση Θέσεων Κράτηση Θέσεων Ακύρωση Κράτησης Θέσεων D same kˆpoiec basikèc prodiagrafèc Basizìmaste sto montèlo Pelˆth-Exuphrèth Upojèsoume sugkekrimènh teqnologða gia thn bˆsh dedomènwn (SQL Server RDBMS) O Exuphrèthc eðnai sundedemènoc me thn bˆsh dedomènwn (topikˆ) Νέο-Ενδιάμεσο Επίπεδο Πελάτη-Εξυπηρέτη Η βάση δεδομένων είναι επίσης εξυπηρέτης O Pelˆthc sundèetai me ton Exuphrèth (endiˆmeso epðpedo) gia na apokt sei prìsbash sth bˆsh dedomènwn (qamhlì epðpedo) ProkÔptoun trða epðpeda sthn arqitektonik
Λογική επέκταση του μοντέλου πελάτη-εξυπηρέτη Χωρίζουμε την λειτουργικότητα σε ανεξάρτητα τμήματα Κάθε τμήμα αναθέτετε σε διαφορετικό εξυπηρέτη (tier) Μια αίτηση μπορεί να απασχολήσει πολλούς εξυπηρέτες Αλυσιδωτές αιτήσεις κατά μήκος των διαφορετικών τμημάτων Parˆdeigma Multi-tier Sust matoc Sthn sunèqeia parembˆloume èna tètarto epðpedo metaxô Exuphrèth kai Bˆshc (epðpedo antikeimènwn) Apemplok tou k dika tou Exuphrèth apo thn dom thc sqesiak c bˆshc dedomènwn Αλλαγές στο επίπεδο των δεδομένων δεν επιρεάζουν τα παραπάνω επίπεδα H epikoinwnða Pelˆth-Exuphrèth gðnetai me antikeðmena pou proèrqontai ( katal goun) apì to (sto) nèo epipèdo Ο πελάτης αγνοεί πλήρως την δομή και εσωτερικές λειτουργίες του επίπεδου δεδομένων ProkÔptoun tèssera epðpeda sthn arqitektonik Sqediˆzoume thn bˆsh dedomènwn qrhsimopoiìntac to sqesiakì montèlo Basizìmaste sto logismikì Microsoft Access H bˆsh dedomènwn perièqei treðc aploôc pðnakec Passenger Flight Reservation H prospèlash/qr sh thc bˆshc den apaiteð thn egkatˆstash tou logismikoô Microsoft Access Gia thn ulopoðhsh tou sust matoc se Java, leitourgoôme wc ex c Χρησιμοποιούμε τους οδηγούς ODBC που προσφέρει το λειτουργικό Windows* Βασιζόμαστε στην βιβλιοθήκη JDBC Σύμφωνα με τον οδηγό /γέφυρα JDBC-ODBC Prospèlash Bˆshc Sunist sa PassangerList static final String DB = "jdbc:odbc:airline"; static final String USER = ""; static final String PASSWD = ""; Connection theconnection; Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); theconnection = DriverManager.getConnection(DB, USER, PASSWD); catch (ClassNotFoundException ex1) { /*... */ catch (SQLException ex2) { /*... */
Anˆgnwsh StoiqeÐwn Sunist sa PassengerUpdate Connection theconnection; String query = "Select Name From Passenger"; Statement stmt = theconnection.createstatement(); ResultSet rs = stmt.executequery(query); // Show Results while (rs.next) { System.out.println(rs.getString(1)); stmt.close(); catch (SQLException ex) { /*... */ Enhmèrwsh/Eisagwg StoiqeÐwn Sunist sa PassengerUpdate final String passangerno = "X123"; final String name = "Pit Cavourias"; String query = "Update Passenger Set Name = " + name + " Where PassengerNo = " + passangerno + " "; Statement stmt = theconnection.createstatement(); int n = stmt.executeupdate(query); // Check if update was successful if (n == 0) { // No record found query = "Insert Into " + "Passenger(PassengerNo,Name) " + "Values( " + passangerno + ", " + name + " )"; n = stmt.executeupdate(query); Prospèlash Bˆshc Sunist sa PassangerList Parˆllhla me ton k dika pou eðdame, prosfèroume mia parˆllhlh ulopoðhsh me thn qr sh thc ADO.NET Basizìmaste sthn Ðdia bˆsh Microsoft Access με τους ίδιους απλούς πίνακες Gia thn ulopoðhsh tou sust matoc se VB.NET, leitourgoôme wc ex c Βασιζόμαστε στην βιβλιοθήκη ADO.NET Parat rhsh: Oi leitourgðec eðnai sqedìn Ðdiec μόνο η γλώσσα προγραμματισμού αλλάζει Const PROVIDER as String = _ "Provider=Microsoft.Jet.OLEDB.4.0;" Const DB as String = "Data source=airline.mdb" Const USER as String = "User Id=admin;Password=;" Const CONNECTION as String = PROVIDER + DB + USER Protected dbconn as SqlConnection Try Create new SQL Connection dbconn = New SqlConnection(CONNECTION) Open connection dbconn.open() Catch ex As System.Data.SqlClient.SqlException... End Try
Anˆgnwsh StoiqeÐwn Sunist sa PassengerUpdate Protected dbconn as SqlConnection Try Dim query As String = "Select Name From Passenger" Create a new SQL Command based on SQL query and current Connection Dim command As New SqlCommand(sqlQuery, dbconn) Dim rs As SqlDataReader = ommand.executereader() Show Results While rs.read() Debug.print(rs.getString(1)) End While rs.close() Catch ex As System.Data.SqlClient.SqlException... End Try Enhmèrwsh/Eisagwg StoiqeÐwn Sunist sa PassengerUpdate Dim passangerno As String = "X123"; Dim name As String = "Pit Cavourias"; Dim query As String = "Update Passenger Set Name = " + name + " Where PassengerNo = " + passangerno + " "; Start a new Transaction Dim dbtrans As SqlTransaction = dbconn.begintransaction() Create a new SQL Command Dim command As New SqlCommand(sqlQuery, dbconn, dbtrans) Execute query Dim commandresult As Integer = command.executenonquery() Commit Transaction dbtrans.commit() // Check if update was successful if (commandresult == 1) then 1 record affected End If PÐsw sthn JAVA H ulopoðhsh se VB.NET / ADO.NET eðnai parìmoia H prospèlash twn dedomènwn apì thn bˆsh gðnetai me thn sunhstìsa ResultSet Ta dedomèna eðnai apojhkeumèna se morf pðnaka Metatrèpoume kˆje gramm tou pðnaka se èna antikeðmeno H prospèlash twn dedomènwn gðnetai me antikeimenostref trìpo UlopoioÔme tic mejìdouc select/insert/update gia kˆje antikeðmeno Me autì ton trìpo kˆje antikeðmeno gnwrðzei ton trìpo apoj keushc twn stoiqeðwn ston antðstoiqo pðnaka Prosfèroume diˆfanh prìsbash sthn bˆsh sta parapˆnw epðpeda k dika p.q. diepaf qr sth-h/u Sunist sa Passenger public class Passenger implements Serializable { String thepassengerno; String thename; String theaddress; String thecity; String thestate; String thezip; String thecreditcard; public Passenger(String passenger_no) { this(passenger_no, "", "", "", "", "", "");
Sunist sa Passenger public Passenger(String passenger_no, String name, String address, String city, String state, String zip, String credit_card) { thepassengerno = passenger_no; thename = name; theaddress = address; thecity = city; thestate = state; thezip = zip; thecreditcard = credit_card; Sunist sa Passenger public String getpassengerno() { return thepassengerno; public String getname() { return thename; public void setname(string name) { thename = name; Sunist sa Passenger public static Passenger getinstance(connection db, String pno) throws SQLException { String query = "Select Name, Address, City, State, " + "Zip, CreditCard From Passenger Where PassengerNo= " + pno + " "; Statement stmt = db.createstatement();parap anw ResultSet rs = stmt.executequery(query); rs.next(); String name = rs.getstring(1); String address = rs.getstring(2); //... String credit_card = rs.getstring(6); rs.close(); stmt.close(); return new Passenger(pno, name, address, city, state, zip, credit_card); Sunist sa Passenger public void dbwrite(connection db) throws SQLException { String query = "Update Passenger Set Name = " + thename + ", Address = " + theaddress + ", City = " + thecity + ", State = " + thestate + ", Zip = " + thezip + ", CreditCard = " + thecreditcard + " " + "Where PassengerNo = " + thepassengerno + " "; Statement stmt = db.createstatement(); if (stmt.executeupdate(query) == 0) { query = "Insert Into Passenger(PassengerNo, " + "Name, Address,City, State, Zip, CreditCard) " + "Values ( " + thepassengerno + ", " + thename + ", " + theaddress + ", " + thecity + ", " + thestate + ", " + thezip + ", " + thecreditcard + " )"; n = stmt.executeupdate(query); stmt.close();
ja ulopoi soume to sôsthma me thn qr sh Sockets EÐnai h basikìterh teqnologða ulopoðhshc Χαμηλότερο επίπεδο από τις υπόλοιπες τεχνολογίες, π.χ. RMI, CORBA Χαρακτηρίζεται ως η assembly του TCP/IP Se analogða me thn assembly ta progrˆmmata pou basðzontai sta Sockets prosfèroun kalôterec epidìseic wc proc thn taqôthta sundeshc, metˆdoshc, klp. Προσφερουν δεν είναι όμως πάντα έτσι Μερικά προγράμματα σε assembly χρησιμοποιούν όση μνήμη χρειάζεται ένα πρόγραμμα σε άλλη γλώσσα και είναι εξίσου αργά (ή σχεδόν το ίδιο) Με τον ίδιο τρόπο ένα πρόγραμμα που χρησιμοποιεί απέυθίας Sockets μπορεί να έχει τις ίδιες επιδώσεις με ένα πρόγραμμα RMI Akìma kai an den eðmaste bèbaioi gia ta pleonekt mata twn Sockets mporoôme na ektim soume to kìstoc H ulopoðhsh me Sockets eðnai sqedìn pˆnta piì dôskolh kai èqei megalôtero kìstoc se sqèsh me tic teqnologðec uyhlìterou epipèdou Αν δεν μεταφέρουμε απλά στοιχεία (ASCII) Αν χρειάζεται να αντιμετωπίσουμε πολλά σφάλματα Αν πρέπει να χρησιμοποιεί πολλαπλούς servers Αν υπάρχουν απαιτήσεις σε ασφάλεια / κρυπτογραφεία O kentrikìc stìqoc den eðnai mia apodotik ulopoðhsh Μπορεί να επιτευχθεί με την χρήση ισχυρότερων μηχανημάτων O stìqoc eðnai na kalôyoume tic prodiagrafèc BeltÐwsh sthn apìdosh den gðnetai potè ek twn protèrwn H klˆsh URL An jèloume na metafèroume dedomèna proc mða kateôjunsh, mporoôme na qrhsimopoi soume to prot kollo HTTP public URL(String url) throws MalformedURLException URL up = new URL("http://www.upatras.gr/index.html"); boolean equals(object x) elègqei thn isìthta metaxô antikeimènwn URL String gethost() epistrèfei to kommˆti pou antistoiqeð sto host www.upatras.gr String getfile() epistrèfei to kommˆti pou antistoiqeð sth selðda index.html int getport() epistrèfei to kommˆti pou antistoiqeð sthn pìrta/jôra 80 InputStream openstream() epistrèfei mia ro pou antistoiqeð sth selðda H klˆsh InetAddress AntiproswpeÔei thn dieôjunsh enìc upologist Qrhsimopoi te apì tic klˆseic Socket kai DatagramPacket H klˆsh den èqei constructor prosfèrei 3 static mejìdouc InetAddress getlocalhost() h dieôjunsh tou topikoô mhqan matoc InetAddress getbyname(string host) h dieôjunsh tou mhqan matoc host getbyname("www.upatras.gr"); InetAddress [] getallbyname(string host) èna pðnaka me ìlec tic dieôjunseic tou mhqan matoc host sthn perðptwsh pou èqei pollaplèc sundèseic 'Olec oi mejìdoi dhmiourgoôn èna UnknownHostException an h dieôjunsh den eðnai swst
H klˆsh Socket Mia monˆda sundedemènh sto DiadÐktuo èqei èna sônolo apì local ports ènac proorismìc mhnumˆtwn sto eswterikì thc upologistik c monˆdac, orðzetai apì ènan akèraio H klˆsh socket sundèete se mða port kai prosfèrei mejìdouc gia thn apostol /parallab mhnumˆtwn proc/apì thn apomakrusmènh monˆda Socket(String host, int port) Socket(InetAddress address, int port) Efìson dhmiourghjeð to antikeðmeno, me th mèjodo getinputstream() dhmiourgoôme èna antikeðmeno tôpou InputStream Me th mèjodo getoutputstream() dhmiourgoôme èna antikeðmeno tôpou OutputStream H klˆsh ServerSocket H klˆsh socket ulopoieð mða local port kai prosfèrei mejìdouc gia thn apostol /parallab mhnumˆtwn ServerSocket(int port) An h local port eðnai desmeumènh dhmiourg tai èna IOException 'Otan mia apomakrôsmènh monˆda epiqurðsei na sundejeð h local port h mèjodoc accept() dhmiourgeð èna antikeðmeno Socket Mèsw tou nèou antikeimènou Socket pragmatopoieðte h epikoinwnða me thn apomakrusmènh monˆda H epikoinwnða pelˆth-exuphrèth basðzetai sta Sockets EpekteÐnoume thn sunistìsa Socket gia na mporoôme na metafèroume antikeðmena (SuperSocket) QrhsimopoioÔme tic sunistìsec ObjectInputStream kai ObjectOutputStream gia thn seiriopoðhsh twn antikeimènwn Gia thn apofug problhmˆtwn me thn metaforˆ antikeimènwn mèsw enìc Socket kˆnoume mia akìma metatrop QrhsimopoioÔme tic sunistìsec ByteInputStream kai ByteOutputStream gia thn metˆdosh twn (seiriopoihmènwn) antikeimènwn upo thn morf reômatoc apì byte Sunist sa SuperSocket public class SuperSocket { Socket m_sock; DataInputStream m_in; DataOutputStream m_out; public SuperSocket(String host, int port) throws UnknownHostException, IOException { this(new Socket(host, port)); public SuperSocket(Socket s) throws UnknownHostException, IOException { m_sock = s; m_in=new DataInputStream(m_sock.getInputStream()); m_out=new DataOutputStream(m_sock.getOutputStream());
Sunist sa SuperSocket public void writevector(vector x) throws IOException { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bytes); out.writeobject(x); byte [] buffer = bytes.tobytearray(); out.close(); m_out.writeint(buffer.length); m_out.write(buffer); Sunist sa SuperSocket public Vector readvector() throws IOException, ClassNotFoundException { int n = m_in.readint(); byte [] buffer = new byte[n]; theinput.read(buffer); ByteArrayInputStream bytes = new ByteArrayInputStream(buffer); ObjectInputStream in = new ObjectInputStream(bytes); Object x = in.readobject(); in.close(); return (Vector) x; UlopoioÔme ton exuphrèth me èna mìno n ma Gia na mporèsoume na exuphret soume polloôc qr stec tautìqrona, h epèktash eðnai sqetikˆ eôkolh Gia kˆje nèa sôndesh, o exuphrèthc anajètei èna nèo antikeðmeno SuperSocket Ta stoiqeða thc aðthshc stèlnontai upì thn morf enìc dianôsmatoc apì antikeðmena H mèjodoc processrequest epexergˆzetai to diˆnusma gia na exuphret sh thn aðthsh tou pelˆth H apˆnthsh tou Exuphrèth eðnai (epðshc) upì thn morf enìc dianôsmatoc apì antikeðmena Sunist sa Server public class Server { public static final int PORT = 1234; static final String DB = "jdbc:odbc:airline"; static final String USER = ""; static final String PASSWD = ""; Connection theconnection; ServerSocket thesocket; SuperSocket theclient;
Sunist sa Server public Server() { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); theconnection = DriverManager.getConnection(DB, USER, PASSWD); thesocket = new ServerSocket(PORT); while (true) { System.err.println("Server is ready."); Socket s = thesocket.accept(); theclient = new SuperSocket(s); processrequest(); catch (Exception ex) { /*... */ Sunist sa Server public void processrequest() { Vector v = theclient.readvector(); String opcode = (String) v.elementat(0); Vector out = null; if (opcode.equals("search Flights")) out = searchflights(); else if (opcode.equals("search Seats")) out = searchseats(v); else if (opcode.equals("book Seat")) out = bookseat(v); else System.err.println("Ignored request"); if (out!= null) theclient.writevector(out); theclient.close(); catch (Exception ex) { /*... */ Sunist sa Server public Vector searchflights() { Vector out = new Vector(); Flight [] flights = Flight.getFlights(theConnection); for (int i = 0; i < flights.length; i++) { String s = flights[i].packasstring(); out.addelement(s); catch (Exception ex) { /*... */ return out; UlopoioÔme ton pelˆth qrhsimopoiìntac sunistìsec tou SWING MporoÔme na emfanðsoume ta Ðdia stoiqeða me diaforetikoôc trìpouc (thin/thick clients) Υλοποίηση ως Applet Χρήση HTML, Flash,...... Gia kˆje aðthsh tou qr sth, o pelˆthc sundèete me ton Exuphrèth kai stèlnei èna diˆnusma apì antikeðmena pou perigrˆfoun thn aðthsh O Pelˆthc den gnwrðzei pwc ekteleðte h aðthsh
Sunist sa RemoteClient public void searchflights() { theresults.settext(""); thesocket = new SuperSocket(HOST, PORT); thesocket.getsocket().setsotimeout(timeout); Vector v = new Vector(); v.addelement("search Flights"); thesocket.writevector(v); v = thesocket.readvector(); thesocket.close(); for (int i = 0; i < v.size(); i++) { String s = (String) v.elementat(i); theresults.append(s + "\n"); catch (Exception ex) { /*... */ Exetˆsame orismèna jèmata pou sqetðzontai me thn bˆsh dedomènwn EpÐpedo Dedomènwn Για την υλοποίηση χρησιμοποιήσαμε τη Microsoft Access Ulopoi same 1 antikeðmeno gia kˆje pðnaka thc bˆshc dedomènwn EpÐpedo Antikeimènwn Kˆname mia gr gorh episkìpish twn basik n sunistìswn apì thn biblioj kh java.net Επεκτίναμε την συνιστόσα Socket για να επιτρέπει την μεταφορά αντικειμένων (διανυσμάτων) Parousiˆsame thn ulopoðhsh gia epilegmèmenec leitourgðec ston Exuphrèth kai Pelˆth O k dikac kai h bˆsh dedomènwn ja anarthjoôn sthn selðda tou maj matoc mazð me epiplèon paradeðgmata Epìmeno Frontist rio H ulopoðhsh twn server kai client se.net eðnai parìmoia Βασιζόμαστε στην βιβλιοθηκη System.Net.Sockets H ulopoðhsh tou SuperSocket gðnetai me thn qr sh NetworkStream Case Study: SÔsthma Krat sewn Aeroporik n Jèsewn Imports System.Net.Sockets UlopoÐhsh sust matoc me RMI Const portnumber As Integer = 8000 Dim tcplistener As New TcpListener(portNumber) tcplistener.start() Try Dim tcpclient As TcpClient = tcplistener.accepttcpclient() Dim networkstream As NetworkStream = tcpclient.getstream()